#ifndef NETLIB_EVENTLOOP_H
#define NETLIB_EVENTLOOP_H

// Reactor类的封装，每个线程最多一个

#include <atomic>
#include <functional>
#include <vector>
#include <boost/any.hpp>

#include "Mutex.h"
#include "CurrentThread.h"
#include "Timestamp.h"
#include "Callbacks.h"
#include "TimerId.h"

namespace netlib
{
namespace net
{

class Channel;
class Poller;
class TimerQueue;

class EventLoop : noncopyable
{
public:
    typedef std::function<void()> Functor;

    EventLoop();

    ~EventLoop();

    void loop(); // 开始事件循环等待

    void quit(); // 停止事件循环等待，可跨线程

    // 返回调用poll结果的时间戳
    Timestamp pollReturnTime() const { return pollReturnTime_; }

    int64_t iteration() const { return iteration_; }

    void runInLoop(Functor cb); // 执行附加任务

    void queueInLoop(Functor cb); // 向附加任务列表中添加任务

    size_t queueSize() const; // 返回附加任务列表的长度

    // 添加一个一次性定时器
    TimerId runAt(Timestamp time, TimerCallback cb);

    // 添加一个一次性定时器，runAt的封装
    TimerId runAfter(double delay, TimerCallback cb);

    // 添加一个重复的定时器
    TimerId runEvery(double interval, TimerCallback cb);
    
    void cancel(TimerId timerId); // 关闭定时器

    void wakeup(); // 唤醒EventLoop所在的创建者线程

    void updateChannel(Channel* channel); // 在Poller中添加或者更新通道

    void removeChannel(Channel* channel); // 从Poller中移除通道

    bool hasChannel(Channel* channel); // 查询该通道是否注册到poll中

    void assertInLoopThread() // 判断调用函数的线程是否为该对象的创建者
    {
        if (!isInLoopThread())
            abortNotInLoopThread(); // 如果不是则程序退出
    }

    // 断言是否在创建者线程中
    bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

    bool eventHandling() const { return eventHandling_; } // 查询是否正在处理事件

    void setContext(const boost::any& context) // 设置用户自定义对象
    { context_ = context; }

    const boost::any& getContext() const // 获得用户自定义const类型的对象引用
    { return context_; }

    boost::any* getMutableContext() // 获得用户自定义对象指针
    { return &context_; }

    static EventLoop* getEventLoopOfCurrentThread(); // 返回当前EventLoop对象的指针

private:
    void abortNotInLoopThread(); // 出现跨线程调用函数，记录错误日志并退出

    void handleRead(); // eventfd触发的处理函数，唤醒该线程

    void doPendingFunctors(); // 运行附加任务

    void printActiveChannels() const; // 打印活动通道

    typedef std::vector<Channel*> ChannelList;

    bool looping_;                              // 是否处于循环状态
    std::atomic<bool> quit_;                    // 是否退出loop()
    bool eventHandling_;                        // 当前是否正在处理事件
    bool callingPendingFunctors_;               // 是否正在运行附加任务
    int64_t iteration_;                         // 记录事件循环的次数，poll的调用次数
    const pid_t threadId_;                      // 所属线程的ID
    Timestamp pollReturnTime_;                  // 调用poll返回的时间戳
    std::unique_ptr<Poller> poller_;            // 智能指针管理的Poller对象
    std::unique_ptr<TimerQueue> timerQueue_;    // 智能指针管理定时器对象
    int wakeupFd_;                              // eventfd，用于线程同步，8个字节的缓冲区
    std::unique_ptr<Channel> wakeupChannel_;    // 与eventfd关联的通道，智能指针管理
    boost::any context_;                        // 用户自定义对象

    ChannelList activeChannels_;                // Poller返回的活动通道
    Channel* currentActiveChannel_;             // 当前正在处理的活动通道

    mutable MutexLock mutex_;                   // 互斥锁（可变的）
    std::vector<Functor> pendingFunctors_ GUARDED_BY(mutex_); // 附加任务列表

}; // class EventLoop end

} // namespace net end

} // namespace netlib end

#endif